; http://code.google.com/p/springer-loader/
; by Ritterbrater
; November 2011
; GNU GPL V3
; file created with notepad2

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.


Gui, Add, Text, x16 y29 w400 h15 , Links (copy from link: Browse This Book -> Contents):
Gui, Add, Edit, x16 y43 w430 h340 , 
Gui, Add, Button, x356 y400 w90 h30 , Go!
Gui, Add, Text, x16 y400 w185 , You accept Terms of Service of Springerlink, HTTrack, Wget, GZip and SpringerLoader
Gui, Add, Text,  , Select downloader:
Gui, Add, Radio, checked vRadios, HTTrack (recommended)
Gui, Add, Radio, , wget (alternative downloader, free configurable)
;Gui, Add, Radio, , experimental Downloader (requires .NET Framework 2.0 or later) ;not yet implemented yet; wget seems to work
Gui, Add, CheckBox, x212 y400 w100 h30 , debug mode
; Generated using SmartGUI Creator 4.0
Gui +Resize
Gui, Show, x246 y195 h520 w470, SpringerLoader 1.4.4
Return

ButtonGo!:

ControlGetText, urls, Edit1
gui, submit
controlget, debugswitch, checked, , debug mode
Gui, Destroy
sleep, 100 ;give time to destroy gui
dummy:=createdownloadcommand("", "", "", Radios)
getdebugstatus(debugswitch)
startdownloading(urls)
;do sth
exitapp

GuiClose:
ExitApp
 

startdownloading(urls)
{

  filedelete, %a_workingdir%\index-2.html 
  filedelete, %a_workingdir%\index-2.html.gz
  filedelete, %a_workingdir%\index-2.html.readme 
  filedelete, %a_workingdir%\index.html 
  filedelete, %a_workingdir%\contents 
  
  SetWorkingDir %A_ScriptDir%

  iniread, par1, %a_scriptdir%\config.ini, Options, launchparameters1
  iniread, par2, %a_scriptdir%\config.ini, Options, launchparameters2

  iniread, showballoon, %a_scriptdir%\config.ini, Options2, showballoontip
  iniread, showfinished, %a_scriptdir%\config.ini, Options2, showfinishedbox
  iniread, par, %a_scriptdir%\config.ini, Options2, filelength
  
  debugmsg("launchparameters1: " . par1 . "`n"  
    . "launchparameters2: " . par2 . "`n" 
    . "showballoontip: " . showballoon . "`n" 
    . "showfinishedbox: " . showfinished . "`n"  
    . "showballoontip: " . showballoon . "`n"  
    . "maximum filenamelength: " . par . "`n")
  
  if (par < 1)
  {
    msgbox Config.ini is corrupted or missing! `n Exit!
    exitapp
  }
  getfilelength(par) ;initialisieren der maximalen Dateinamenlänge
  
  urls := urls . "`n"
  
  anzurls := counturls(urls)
  showballoon(0, "Buch", anzurls, showballoon)
  
  loop
  {

    stringgetpos, pos, urls, `n
    if pos < 1 then
      break
    stringleft, url, urls, pos
    stringtrimleft, urls, urls, pos + 1 ;to remove leading new line `n
   
    url := getmainurl(url)

    if strlen(url) < 4
    {
      debugmsg("URL will be ignored: " . url . "`n`nSpringerLoader will continue")
      continue ;errorneous url, continue with next one
    }
      
    download(url, par1, par2)
    
    ;workaround for wget
    if fileexist(a_scriptdir . "\index-2.html") && (fileexist(a_scriptdir . "\index.html") fileexist(a_scriptdir . "\contents"))
    {
      filedelete, %a_scriptdir%\index-2.html
    }
    if fileexist(a_scriptdir . "\index.html")
    {
      filemove, %a_scriptdir%\index.html, %a_scriptdir%\index-2.html.gz
      runwait, gunzip.exe -fd index-2.html.gz,,hide
    }
    if fileexist(a_scriptdir . "\contents")
    {
      filemove, %a_scriptdir%\contents, %a_scriptdir%\index-2.html.gz
      runwait, gunzip.exe -fd index-2.html.gz,,hide
    }
    
    
    filegetsize, groe, %a_scriptdir%\index-2.html, k
    if(errorlevel)
    {
      debugmsg("Book website could not be downloaded `n"
        . "File is missing: " . a_scriptdir . "\index-2.html `n" 
        . "from URL: " . url
        . "`nPlease review HTTrack log file: " . a_scriptdir . "\hts-log.txt"
        . "`nand Wget log file: " . a_scriptdir . "\wget-log.txt"
        . "`n`n`nSpringerLoader will continue")
      continue
    }
    else if groe < 10 ;Fehlerhaft!
    {
      debugmsg("File will be ignored: " . a_scriptdir . "\index-2.html `n" 
        . "from URL: " . url 
        . "`nPlease review HTTrack log file: " . a_scriptdir . "\hts-log.txt"
        . "`nand Wget log file: " . a_scriptdir . "\wget-log.txt"
        . "`n`nThis file is very small and may contain no book`nSpringerLoader will continue")
      continue ;do not delete files for debugging!
    }
    downloadfromparsing(par1, par2)
  }
  
  showballoon(-99, "Buch") ;Finished balloon tip

  if(!showfinished && showballoon)
    sleep, 5005
  
  if (showfinished)
    msgbox Finished!
exitapp
}
;---

downloadfromparsing(par1, par2)
{
  ;constants
  fname1 := "fulltext.pdf"
  fname2 := "front-matter.pdf"
  fname3 := "back-matter.pdf"

  searchstring1:="fulltext.pdf"
  searchstring2:="front-matter.pdf""" . " "
  searchstring3:="back-matter.pdf""" . " "

  specialtitle2 := "Front_matter"
  specialtitle3 := "Back_matter"

  static anzfinished = 0
  
  ;stringgetpos, pos, url, /, R2
  ;stringleft, url2, url, pos
  ;msgbox, %url2%

  ;FileSelectFile, file
  
  file := a_scriptdir . "\index-2.html" ;es gibt keine index.html
  
  booktitle := extracttitle(file)
  booktitle := debuginput("Book title ok? `nThe book folder will be named by book title. `n`nIt must be at least 4 characters long!`n"
    . "If book folder already exists it will be numbered.", booktitle, 4)
  booktitle := correctfile(booktitle)
  if strlen(booktitle) < 4
  {
    debugmsg("This book will be ignored because book title is too short! `n" 
      . "(You should not see this message)")
    return
  }
   
  destfolder := trycreatefolder(booktitle)

  ;cover image
  cover := extractcover(file)
  title := "http://www.springerlink.com" . cover
  download(title, par1, par2)
  trymovefile(destfolder, "cover-large.gif", "cover.gif", 98)
  

    i = 1
    ;"/content/jq516w7924701460/fulltext.pdf"
    Loop, read, %file%
    {
      line := A_LoopReadLine
      

      loop, 3 ; %a_index% from 1 to 3
      {
      
        if (instr(line, searchstring%a_index%) > 0)
        {

          ;URL rausfischen
          ftempname := fname%a_index%  ;index workaround for next line
          stringgetpos, pos, line, %ftempname%, R
          stringleft, title, line, pos + strlen(ftempname)
          stringgetpos, pos, title, ", R
          stringright, title, title, strlen(title) - pos-1
          fturl := "http://www.springerlink.com" . title
          
          ;urls0x%i% := title
          
          ;msgbox %title% `n %oldline%
                
          ;Kapitelname
          
          if (a_index = 1) ;only for real chapters
          {
            stringgetpos, pos, oldline, </a>
            stringgetpos, posspan, oldline, <span class="subtitle">
            ;Bug; manchmal sind die Kapitelnamen leer, dann nach nächsten '<' suchen
            if ((posspan < 10) && (posspan > -1)) ;-1 ~ not found
            {
              stringgetpos, pos, oldoldline, <, R
              oldline := oldoldline
            }
            stringleft, title, oldline, pos
            stringgetpos, pos, title, >, R
            stringright, title, title, strlen(title) - pos-1
            ftname := correctfile(title)
          }
          else
            ftname := specialtitle%a_index%   ;for front and back matter

          ;msgbox, %fturl% %a_index%

          download(fturl, par1, par2)
          trymovefile(destfolder, ftempname, ftname . ".pdf", i, fturl)

          ;urls1x%i% := title
          
          ;msgbox %title%
          i := i + 1
        }

        
      }
      
      ;remind old read lines for chapter names
      oldoldline := oldline ;Bug, wenn Unterkapitelnamen; Beispiel: http://www.springerlink.de/content/978-3-8348-0172-2/contents/
                                                                  ;attention: url must be updated via browser
      oldline := A_LoopReadLine
    }
   

  ;zuletzt noch Index verschieben

  trymovefile(destfolder, "index-2.html", "about.html", 99)
  
  anzfinished := anzfinished + 1
  
  showballoon(anzfinished, booktitle)

  return
}
;----------------------

download(url, par1, par2)
{
  url := debuginput("URL correct? Are all slashes correct? `n`nPlease check URL carefully!", url)
  ;cmd:="httrack.exe " . par1 . " " . url . " " . par2 . " " . a_workingdir
  ;cmd:="cmd /c pause | httrack.exe " . par1 . " " . url . " " . par2 . " " . a_workingdir ;working but not needed anymore
  cmd:=createdownloadcommand(url, par1, par2)
  cmd := debuginput("Command correct?", cmd)
  ;msgbox, %cmd%
  ;runwait, %cmd%
  runwait, %cmd%,,hide
  sleep, 500
  ;msgbox sleep
}

createdownloadcommand(url, par1, par2, downloader = 0)
{
  static chosen = 0
  cmd:=""
  if downloader > 0
  {
    chosen := downloader
  }
  else
  {
    if chosen = 1
      cmd:="httrack.exe " . par1 . " " . url . " " . par2 . " " . a_workingdir
    else if chosen = 2
      cmd:="wget.exe -o wget-log.txt " . url
    else
      msgbox bug?
  }
  return cmd
}

getmainurl(url)
{
  stringgetpos, pos, url, doi.org
  if pos > 0 then
  {
    stringgetpos, urlpos, url, /, R
    if strlen(url) - urlpos = 1
      stringleft, url, url, strlen(url) - 1
    stringgetpos, urlpos, url, /, R
    stringright, url2, url, strlen(url) - urlpos
    url2 := "http://www.springerlink.com/content" . url2
  }  
  else
  {
    stringgetpos, urlpos, url, content/
    urlpos2 := urlpos + 9 ;offset for word content/
    stringgetpos, urlpos, url, /,, urlpos2  ;find next / relative to content/
    if ErrorLevel ;if user erases all / after isbn
    {
      url2 := url . "/"
      stringgetpos, urlpos2, url2, /,, urlpos2
      stringleft, url2, url2, urlpos2
    }
    else
      stringleft, url2, url, urlpos
  }
  if (strlen(url2) < 4 && !getdebugstatus())
    inputbox, a, Error, Error at following URL: `n`nSoftware will continue with next URL!,,,,,,,,%url%
  else
    url2 := url2 . "/contents/"
  url2 := debuginput("URL correct? `nIt must look like this:`n" 
    . "http://springerlink.com/content/978-1-234-56789-0/contents/" 
    . "`n`nCheck Slashes `n`nPlease check URL carefully!", url2)
  return url2
}

extracttitle(file)
{
  i = 0
  ;<dt>Title</dt>
  Loop, read, %file%
  {
    if (instr(A_LoopReadLine, "<dt>Title</dt>") > 0)
    {
      line := a_loopreadline
      break
    }
  }
  
  stringgetpos, pos, line, <dt>Title</dt>
  stringright, title, line, strlen(line) - pos - strlen("<dt>Title</dt>")
  
  
  loop
  {
    stringgetpos, pos, title, >
    if pos < 5
      stringright, title, line, strlen(title) - pos - 1
    else
      break
  }
  
  stringgetpos, pos, title, <
  stringleft, title, title, pos
  title := correctfile(title)
  
  return title
}

correctfile(title)
{
  ;http://de.autohotkey.com/forum/post-52193.html&sid=bdee8fd290daaebc43c34bf2ce147aa6#52193
  a = ,
  StringReplace, title, title, %A_SPACE%, _, All
  StringReplace, title, title, %A_Tab%, _, All
  StringReplace, title, title, Ã¤, ae, All
  StringReplace, title, title, Ã, Ae, All
  StringReplace, title, title, Ã¼, ue, All
  StringReplace, title, title, Ã, Ue, All
  StringReplace, title, title, Ã¶, oe, All
  StringReplace, title, title, Ã, Oe, All
  
  StringReplace, title, title, Ã, ss, All
  StringReplace, title, title, %a%, , All ;kill comma
  
  StringReplace, title, title, ä, ae, All
  StringReplace, title, title, Ä, Ae, All
  StringReplace, title, title, ü, ue, All
  StringReplace, title, title, Ü, Ue, All
  StringReplace, title, title, ö, oe, All
  StringReplace, title, title, Ö, Oe, All
  
  StringReplace, title, title, ß, ss, All
  
  ;even more problems: http://en.wikipedia.org/wiki/Filename
  a = :
  StringReplace, title, title, %a%, _, All
  a = \
  StringReplace, title, title, %a%, _, All
  a = /
  StringReplace, title, title, %a%, _, All
  a = ?
  StringReplace, title, title, %a%, _, All
  a = `%
  StringReplace, title, title, %a%, _, All
  a = *
  StringReplace, title, title, %a%, _, All
  a = |
  StringReplace, title, title, %a%, _, All
  a = ""
  StringReplace, title, title, %a%, _, All
  a = <
  StringReplace, title, title, %a%, _, All
  a = >
  StringReplace, title, title, %a%, _, All
  ;a = .
  ;StringReplace, title, title, %a%, _, All
  
  ;replace any other 
  title2 := regexreplace(title, "[^a-zA-Z0-9_.-]", "_")
  title := title2
  ;cut very long file names after x chars
  len := getfilelength() 
  stringleft, title, title, %len%
  return title
}

extractcover(file)
{
  i = 0
  ;(/content/u6l5p0/cover-medium.gif)
  Loop, read, %file%
  {
    if (instr(A_LoopReadLine, "cover-") > 0)
    {
      line := a_loopreadline
      break
    }
  }

  stringgetpos, pos, line, ), R
  stringleft, title, line, pos
  stringgetpos, pos, title, (, R
  stringright, title, title, strlen(title) - pos-1
  
  ;even large cover is availible; download it!
  stringleft, title, title, strlen(title) - strlen("medium.gif")
  title := title . "large.gif"



  ;title := correctfile(title)
  
  return title
  
}

trycreatefolder(name)
{
  name := A_ScriptDir . "\" . name
  name2 := name
  i := 0
  if !FileExist(name2)
    filecreatedir, %name2%
  else
  {
    i := 0
    loop
    {
      i := i + 1
      
      if i < 10 ;zweistellig sollte reichen
        name2 := name . "_0" . i
      else
        name2 := name . i
        
      if !FileExist(name2)
      {
        filecreatedir, %name2%
        break
      }
    }
  }
    
  return name2
}

trymovefile(path, sourcename, name, number, fturl = "")
{
  if(getdebugstatus())
  {
    if(fileexist(a_workingdir . "\" . sourcename))
    {
      name := debuginput("File " . sourcename . " was found`n" 
        . "Please check destination file name`n" 
        . "`n`nThe file number will be: " . number, name)
      name := correctfile(name)
    }
    else
    {
      text :="File " . sourcename . " was NOT found`nfrom following source URL: " . fturl
        . "`nPlease review HTTrack log file: " . a_scriptdir . "\hts-log.txt"
        . "`nand Wget log file: " . a_scriptdir . "\wget-log.txt"
        . "`n`n`nMaybe you do not full access?"
      inputbox, a, Error, %text%,,,,,,,,%fturl%
    }
  }

  if number < 10 ;zweistellig sollte reichen
    name2 := "0" . number
  else
    name2 := number
  filemove, %a_workingdir%\%sourcename%, %path%\%name2%_%name%
  filedelete, %a_workingdir%\%sourcename%.readme ;Restmüll von httrack entfernen
}

getfilelength(len = 0)
{
  static length = 0
  if (len <> 0)
    length := len
  return length
}

counturls(urls)
{
  i := 0
  loop
  {
    stringgetpos, pos, urls, `n
    if pos < 1 then
      break
    stringleft, url, urls, pos - 1
    stringtrimleft, urls, urls, pos + 1
    i := i + 1
  }
  return i
}


showballoon(anzfinished, buchname, uanzurls = 0, ushowballoon = 0)
{
  static anzurls = 0
  static showballoon = 0
  if (uanzurls <> 0)
  {
    anzurls := uanzurls
    showballoon := ushowballoon 

  }
  if ((showballoon > 0) && (anzfinished > 0))
  {
    stringleft, buchname, buchname, 20
    text := "[" . anzfinished . "|" . anzurls . "] " . buchname . "..."
    Traytip, , %text%, , 17
    SetTimer, RemoveTrayTip, 3000
  }
  
  if (anzfinished < -2)
  {
    text := "All finished!"
    Traytip, , %text%, , 17
    SetTimer, RemoveTrayTip, 5000
    
  }
}


RemoveTrayTip:
SetTimer, RemoveTrayTip, Off
TrayTip
return


getdebugstatus(debugstatus = 0)
{
  static status = 0
  if (debugstatus <> 0)
    status = debugstatus
    
  return status
}


debugmsg(text)
{
  if(getdebugstatus())
    msgbox %text%
}


debuginput(msg, defaulttext = "", minimumlength = 1)
{
  entered := 0
  
  if(getdebugstatus())
  {

    while (entered == 0)
    {
    inputbox, text,, %msg%,,550,,,,,,%defaulttext%
    if (ErrorLevel or (strlen(text) < minimumlength))
      entered := 0
    else
      entered := 1
    }

    return text
  }
  else
    return defaulttext
}